#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
基金排行数据查询模块

该模块提供基金排行数据的查询、统计和分析功能
支持按日期、基金类型、排序字段等条件进行数据查询
"""

import os
import sys
import django
from datetime import datetime, timedelta
from decimal import Decimal
from typing import List, Dict, Optional, Any

# 添加项目根目录到Python路径
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

# 设置Django环境
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'wealth_backend.settings')
django.setup()

from data_service.models import FundNavRanking
from django.db.models import Q, Max, Min, Avg, Count
from django.utils import timezone


class FundNavRankingStatsQuery:
    """
    基金排行数据查询类
    """
    
    def __init__(self):
        self.model = FundNavRanking
    
    def get_latest_ranking_data(self, 
                               limit: int = 50,
                               fund_type: Optional[str] = None,
                               sort_by: str = 'daily_growth_rate',
                               order: str = 'desc') -> Dict[str, Any]:
        """
        获取最新的基金排行数据
        
        Args:
            limit: 返回记录数量限制
            fund_type: 基金类型过滤
            sort_by: 排序字段
            order: 排序方向 (asc/desc)
            
        Returns:
            包含基金排行数据和统计信息的字典
        """
        try:
            # 获取最新日期
            latest_date = self.model.objects.aggregate(
                latest=Max('ranking_date')
            )['latest']
            
            if not latest_date:
                return {
                    'status': 'error',
                    'message': '暂无基金排行数据',
                    'data': [],
                    'statistics': {}
                }
            
            # 构建查询
            queryset = self.model.objects.filter(ranking_date=latest_date)
            
            # 基金类型过滤
            if fund_type:
                queryset = queryset.filter(fund_type__icontains=fund_type)
            
            # 排序
            valid_sort_fields = [
                'daily_growth_rate', 'weekly_growth_rate', 'monthly_growth_rate',
                'quarterly_growth_rate', 'half_year_growth_rate', 'yearly_growth_rate',
                'two_year_growth_rate', 'three_year_growth_rate', 'since_inception_growth_rate',
                'unit_nav', 'cumulative_nav', 'fund_scale'
            ]
            
            if sort_by in valid_sort_fields:
                order_prefix = '-' if order == 'desc' else ''
                queryset = queryset.order_by(f'{order_prefix}{sort_by}', '-created_at')
            else:
                queryset = queryset.order_by('-daily_growth_rate', '-created_at')
            
            # 限制数量
            if limit > 0:
                queryset = queryset[:limit]
            
            # 序列化数据
            data = []
            for item in queryset:
                data.append({
                    'id': item.id,
                    'fund_code': item.fund_code,
                    'fund_name': item.fund_name,
                    'ranking_date': item.ranking_date.strftime('%Y-%m-%d') if item.ranking_date else None,
                    'unit_nav': float(item.unit_nav) if item.unit_nav else None,
                    'cumulative_nav': float(item.cumulative_nav) if item.cumulative_nav else None,
                    'daily_growth_rate': float(item.daily_growth_rate) if item.daily_growth_rate else None,
                    'weekly_growth_rate': float(item.weekly_growth_rate) if item.weekly_growth_rate else None,
                    'monthly_growth_rate': float(item.monthly_growth_rate) if item.monthly_growth_rate else None,
                    'quarterly_growth_rate': float(item.quarterly_growth_rate) if item.quarterly_growth_rate else None,
                    'half_year_growth_rate': float(item.half_year_growth_rate) if item.half_year_growth_rate else None,
                    'yearly_growth_rate': float(item.yearly_growth_rate) if item.yearly_growth_rate else None,
                    'two_year_growth_rate': float(item.two_year_growth_rate) if item.two_year_growth_rate else None,
                    'three_year_growth_rate': float(item.three_year_growth_rate) if item.three_year_growth_rate else None,
                    'since_inception_growth_rate': float(item.since_inception_growth_rate) if item.since_inception_growth_rate else None,
                    'fund_type': item.fund_type,
                    'fund_company': item.fund_company,
                    'fund_manager': item.fund_manager,
                    'fund_scale': float(item.fund_scale) if item.fund_scale else None,
                    'establishment_date': item.establishment_date.strftime('%Y-%m-%d') if item.establishment_date else None,
                    'purchase_status': item.purchase_status,
                    'redemption_status': item.redemption_status,
                    'management_fee_rate': float(item.management_fee_rate) if item.management_fee_rate else None,
                    'custodian_fee_rate': float(item.custodian_fee_rate) if item.custodian_fee_rate else None,
                    'sales_service_fee_rate': float(item.sales_service_fee_rate) if item.sales_service_fee_rate else None,
                    'created_at': item.created_at.strftime('%Y-%m-%d %H:%M:%S') if item.created_at else None,
                    'updated_at': item.updated_at.strftime('%Y-%m-%d %H:%M:%S') if item.updated_at else None,
                })
            
            # 获取统计信息
            statistics = self.get_ranking_statistics(latest_date, fund_type)
            
            return {
                'status': 'success',
                'data': data,
                'statistics': statistics,
                'query_params': {
                    'date': latest_date.strftime('%Y-%m-%d'),
                    'limit': limit,
                    'fund_type': fund_type,
                    'sort_by': sort_by,
                    'order': order
                }
            }
            
        except Exception as e:
            return {
                'status': 'error',
                'message': f'查询失败: {str(e)}',
                'data': [],
                'statistics': {}
            }
    
    def get_ranking_by_date(self, 
                           target_date: str,
                           limit: int = 50,
                           fund_type: Optional[str] = None,
                           sort_by: str = 'daily_growth_rate',
                           order: str = 'desc') -> Dict[str, Any]:
        """
        根据指定日期获取基金排行数据
        
        Args:
            target_date: 目标日期 (YYYY-MM-DD格式)
            limit: 返回记录数量限制
            fund_type: 基金类型过滤
            sort_by: 排序字段
            order: 排序方向 (asc/desc)
            
        Returns:
            包含基金排行数据和统计信息的字典
        """
        try:
            # 解析日期
            try:
                date_obj = datetime.strptime(target_date, '%Y-%m-%d').date()
            except ValueError:
                return {
                    'status': 'error',
                    'message': '日期格式错误，请使用YYYY-MM-DD格式',
                    'data': [],
                    'statistics': {}
                }
            
            # 构建查询
            queryset = self.model.objects.filter(ranking_date=date_obj)
            
            # 基金类型过滤
            if fund_type:
                queryset = queryset.filter(fund_type__icontains=fund_type)
            
            # 排序
            valid_sort_fields = [
                'daily_growth_rate', 'weekly_growth_rate', 'monthly_growth_rate',
                'quarterly_growth_rate', 'half_year_growth_rate', 'yearly_growth_rate',
                'two_year_growth_rate', 'three_year_growth_rate', 'since_inception_growth_rate',
                'unit_nav', 'cumulative_nav', 'fund_scale'
            ]
            
            if sort_by in valid_sort_fields:
                order_prefix = '-' if order == 'desc' else ''
                queryset = queryset.order_by(f'{order_prefix}{sort_by}', '-created_at')
            else:
                queryset = queryset.order_by('-daily_growth_rate', '-created_at')
            
            # 限制数量
            if limit > 0:
                queryset = queryset[:limit]
            
            # 序列化数据
            data = []
            for item in queryset:
                data.append({
                    'id': item.id,
                    'fund_code': item.fund_code,
                    'fund_name': item.fund_name,
                    'ranking_date': item.ranking_date.strftime('%Y-%m-%d') if item.ranking_date else None,
                    'unit_nav': float(item.unit_nav) if item.unit_nav else None,
                    'cumulative_nav': float(item.cumulative_nav) if item.cumulative_nav else None,
                    'daily_growth_rate': float(item.daily_growth_rate) if item.daily_growth_rate else None,
                    'weekly_growth_rate': float(item.weekly_growth_rate) if item.weekly_growth_rate else None,
                    'monthly_growth_rate': float(item.monthly_growth_rate) if item.monthly_growth_rate else None,
                    'quarterly_growth_rate': float(item.quarterly_growth_rate) if item.quarterly_growth_rate else None,
                    'half_year_growth_rate': float(item.half_year_growth_rate) if item.half_year_growth_rate else None,
                    'yearly_growth_rate': float(item.yearly_growth_rate) if item.yearly_growth_rate else None,
                    'two_year_growth_rate': float(item.two_year_growth_rate) if item.two_year_growth_rate else None,
                    'three_year_growth_rate': float(item.three_year_growth_rate) if item.three_year_growth_rate else None,
                    'since_inception_growth_rate': float(item.since_inception_growth_rate) if item.since_inception_growth_rate else None,
                    'fund_type': item.fund_type,
                    'fund_company': item.fund_company,
                    'fund_manager': item.fund_manager,
                    'fund_scale': float(item.fund_scale) if item.fund_scale else None,
                    'establishment_date': item.establishment_date.strftime('%Y-%m-%d') if item.establishment_date else None,
                    'purchase_status': item.purchase_status,
                    'redemption_status': item.redemption_status,
                    'management_fee_rate': float(item.management_fee_rate) if item.management_fee_rate else None,
                    'custodian_fee_rate': float(item.custodian_fee_rate) if item.custodian_fee_rate else None,
                    'sales_service_fee_rate': float(item.sales_service_fee_rate) if item.sales_service_fee_rate else None,
                    'created_at': item.created_at.strftime('%Y-%m-%d %H:%M:%S') if item.created_at else None,
                    'updated_at': item.updated_at.strftime('%Y-%m-%d %H:%M:%S') if item.updated_at else None,
                })
            
            # 获取统计信息
            statistics = self.get_ranking_statistics(date_obj, fund_type)
            
            return {
                'status': 'success',
                'data': data,
                'statistics': statistics,
                'query_params': {
                    'date': target_date,
                    'limit': limit,
                    'fund_type': fund_type,
                    'sort_by': sort_by,
                    'order': order
                }
            }
            
        except Exception as e:
            return {
                'status': 'error',
                'message': f'查询失败: {str(e)}',
                'data': [],
                'statistics': {}
            }
    
    def get_ranking_statistics(self, target_date, fund_type: Optional[str] = None) -> Dict[str, Any]:
        """
        获取基金排行统计信息
        
        Args:
            target_date: 目标日期
            fund_type: 基金类型过滤
            
        Returns:
            统计信息字典
        """
        try:
            # 构建查询
            queryset = self.model.objects.filter(ranking_date=target_date)
            
            if fund_type:
                queryset = queryset.filter(fund_type__icontains=fund_type)
            
            # 基本统计
            total_funds = queryset.count()
            
            if total_funds == 0:
                return {
                    'total_funds': 0,
                    'fund_types': {},
                    'growth_rate_stats': {},
                    'nav_stats': {},
                    'scale_stats': {}
                }
            
            # 基金类型分布
            fund_types = queryset.values('fund_type').annotate(
                count=Count('fund_type')
            ).order_by('-count')
            
            fund_type_stats = {}
            for item in fund_types:
                fund_type_stats[item['fund_type']] = item['count']
            
            # 增长率统计
            growth_stats = queryset.aggregate(
                daily_avg=Avg('daily_growth_rate'),
                daily_max=Max('daily_growth_rate'),
                daily_min=Min('daily_growth_rate'),
                weekly_avg=Avg('weekly_growth_rate'),
                monthly_avg=Avg('monthly_growth_rate'),
                yearly_avg=Avg('yearly_growth_rate')
            )
            
            # 净值统计
            nav_stats = queryset.aggregate(
                unit_nav_avg=Avg('unit_nav'),
                unit_nav_max=Max('unit_nav'),
                unit_nav_min=Min('unit_nav'),
                cumulative_nav_avg=Avg('cumulative_nav'),
                cumulative_nav_max=Max('cumulative_nav'),
                cumulative_nav_min=Min('cumulative_nav')
            )
            
            # 规模统计
            scale_stats = queryset.aggregate(
                scale_avg=Avg('fund_scale'),
                scale_max=Max('fund_scale'),
                scale_min=Min('fund_scale')
            )
            
            # 获取最新更新时间
            latest_update = queryset.aggregate(
                latest=Max('created_at')
            )['latest']
            
            return {
                'total_funds': total_funds,
                'fund_types': fund_type_stats,
                'growth_rate_stats': {
                    'daily_avg': float(growth_stats['daily_avg']) if growth_stats['daily_avg'] else None,
                    'daily_max': float(growth_stats['daily_max']) if growth_stats['daily_max'] else None,
                    'daily_min': float(growth_stats['daily_min']) if growth_stats['daily_min'] else None,
                    'weekly_avg': float(growth_stats['weekly_avg']) if growth_stats['weekly_avg'] else None,
                    'monthly_avg': float(growth_stats['monthly_avg']) if growth_stats['monthly_avg'] else None,
                    'yearly_avg': float(growth_stats['yearly_avg']) if growth_stats['yearly_avg'] else None,
                },
                'nav_stats': {
                    'unit_nav_avg': float(nav_stats['unit_nav_avg']) if nav_stats['unit_nav_avg'] else None,
                    'unit_nav_max': float(nav_stats['unit_nav_max']) if nav_stats['unit_nav_max'] else None,
                    'unit_nav_min': float(nav_stats['unit_nav_min']) if nav_stats['unit_nav_min'] else None,
                    'cumulative_nav_avg': float(nav_stats['cumulative_nav_avg']) if nav_stats['cumulative_nav_avg'] else None,
                    'cumulative_nav_max': float(nav_stats['cumulative_nav_max']) if nav_stats['cumulative_nav_max'] else None,
                    'cumulative_nav_min': float(nav_stats['cumulative_nav_min']) if nav_stats['cumulative_nav_min'] else None,
                },
                'scale_stats': {
                    'scale_avg': float(scale_stats['scale_avg']) if scale_stats['scale_avg'] else None,
                    'scale_max': float(scale_stats['scale_max']) if scale_stats['scale_max'] else None,
                    'scale_min': float(scale_stats['scale_min']) if scale_stats['scale_min'] else None,
                },
                'latest_update': latest_update.strftime('%Y-%m-%d %H:%M:%S') if latest_update else None,
                'target_date': target_date.strftime('%Y-%m-%d') if target_date else None
            }
            
        except Exception as e:
            return {
                'error': f'统计信息获取失败: {str(e)}'
            }
    
    def get_top_performers(self, 
                          period: str = 'daily',
                          limit: int = 10,
                          fund_type: Optional[str] = None) -> Dict[str, Any]:
        """
        获取表现最佳的基金
        
        Args:
            period: 时间周期 (daily, weekly, monthly, yearly)
            limit: 返回数量
            fund_type: 基金类型过滤
            
        Returns:
            表现最佳基金列表
        """
        try:
            # 获取最新日期
            latest_date = self.model.objects.aggregate(
                latest=Max('ranking_date')
            )['latest']
            
            if not latest_date:
                return {
                    'status': 'error',
                    'message': '暂无基金排行数据',
                    'data': []
                }
            
            # 构建查询
            queryset = self.model.objects.filter(ranking_date=latest_date)
            
            if fund_type:
                queryset = queryset.filter(fund_type__icontains=fund_type)
            
            # 根据周期选择排序字段
            sort_field_map = {
                'daily': 'daily_growth_rate',
                'weekly': 'weekly_growth_rate',
                'monthly': 'monthly_growth_rate',
                'yearly': 'yearly_growth_rate'
            }
            
            sort_field = sort_field_map.get(period, 'daily_growth_rate')
            queryset = queryset.order_by(f'-{sort_field}', '-created_at')[:limit]
            
            # 序列化数据
            data = []
            for item in queryset:
                growth_rate = getattr(item, sort_field)
                data.append({
                    'fund_code': item.fund_code,
                    'fund_name': item.fund_name,
                    'fund_type': item.fund_type,
                    'fund_company': item.fund_company,
                    'growth_rate': float(growth_rate) if growth_rate else None,
                    'unit_nav': float(item.unit_nav) if item.unit_nav else None,
                    'cumulative_nav': float(item.cumulative_nav) if item.cumulative_nav else None,
                    'fund_scale': float(item.fund_scale) if item.fund_scale else None,
                    'ranking_date': item.ranking_date.strftime('%Y-%m-%d') if item.ranking_date else None
                })
            
            return {
                'status': 'success',
                'data': data,
                'period': period,
                'limit': limit,
                'fund_type': fund_type,
                'date': latest_date.strftime('%Y-%m-%d')
            }
            
        except Exception as e:
            return {
                'status': 'error',
                'message': f'查询失败: {str(e)}',
                'data': []
            }


def main():
    """
    主函数 - 用于测试查询功能
    """
    query = FundNavRankingStatsQuery()
    
    print("=== 基金排行数据查询测试 ===")
    
    # 测试获取最新排行数据
    print("\n1. 获取最新排行数据 (前10名):")
    result = query.get_latest_ranking_data(limit=10)
    if result['status'] == 'success':
        print(f"查询成功，共 {len(result['data'])} 条记录")
        print(f"数据日期: {result['query_params']['date']}")
        print(f"总基金数: {result['statistics']['total_funds']}")
        
        # 显示前5名
        for i, fund in enumerate(result['data'][:5], 1):
            print(f"{i}. {fund['fund_name']} ({fund['fund_code']}) - 日涨幅: {fund['daily_growth_rate']:.2f}%")
    else:
        print(f"查询失败: {result['message']}")
    
    # 测试获取表现最佳基金
    print("\n2. 获取日涨幅最佳基金 (前5名):")
    result = query.get_top_performers(period='daily', limit=5)
    if result['status'] == 'success':
        print(f"查询成功，共 {len(result['data'])} 条记录")
        for i, fund in enumerate(result['data'], 1):
            print(f"{i}. {fund['fund_name']} - 日涨幅: {fund['growth_rate']:.2f}%")
    else:
        print(f"查询失败: {result['message']}")


if __name__ == '__main__':
    main()